package dao;

import java.util.List;
import models.PrivateMessage;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;

/**
 * This Dao contains all the models and finders for handlin the private
 * messages.
 *
 * @author Sander
 */
public class PrivateMessageDao {

    private final Session session;

    public PrivateMessageDao(Session session) {
        this.session = session;
    }

    /**
     * Searches for all the private messages and returns them in a list.
     *
     * @return
     */
    public List<PrivateMessage> findAll() {
        Transaction tx = session.beginTransaction();
        List<PrivateMessage> list = session.createQuery("from PrivateMessage ORDER BY id DESC").setMaxResults(15).list();
        tx.commit();
        return list;
    }

    /**
     * Searches all the private messages with the given folder and user; And
     * returns them in a list.
     *
     * @param folder
     * @param user
     * @return
     */
    public List<PrivateMessage> findAllByFolder(String folder, long user) {
        Transaction tx = session.beginTransaction();
        String where = "(folder = '1') AND receiver = '" + user + "' AND owner = '" + user + "'";
        if (folder.equals("outbox")) {
            where = "folder = '2' AND sender = '" + user + "' AND owner = '" + user + "'";
        } else if (folder.equals("trash")) {
            where = "folder = '3' AND (sender = '" + user + "' OR receiver = '" + user + "') AND owner = '" + user + "'";
        }
        List<PrivateMessage> list = session.createQuery("from PrivateMessage where " + where + " ORDER BY id DESC").setMaxResults(15).list();
        tx.commit();
        return list;
    }

    /**
     * Searches a private message with the given id and returns it in a list.
     *
     * @param id
     * @return
     */
    public List<PrivateMessage> findAllById(long id) {
        Transaction tx = session.beginTransaction();
        List<PrivateMessage> list = session.createQuery("from PrivateMessage where id = :id").setParameter("id", id).list();
        tx.commit();
        return list;
    }

    /**
     * Searches for all private messages with the given id which are not read
     * yet; And returns the count of these private messages.
     *
     * @param user
     * @return
     */
    public int getUnreadMessages(long user) {
        Transaction tx = session.beginTransaction();
        String where = "receiver = '" + user + "' AND owner = '" + user + "' AND status = '1'";
        List<PrivateMessage> list = session.createQuery("from PrivateMessage where " + where + " ORDER BY id DESC").list();
        tx.commit();
        return list.size();
    }

    /**
     * Searches for the private messages with the given page, folder and user;
     * The page is used to show only a few private messages.
     *
     * @param page
     * @param folder
     * @param user
     * @return
     */
    public List<PrivateMessage> getPagination(int page, String folder, long user) {
        int offset = (page - 1) * 15;
        String where = "(folder = '1') AND receiver = '" + user + "' AND owner = '" + user + "'";
        if (folder.equals("outbox")) {
            where = "folder = '2' AND sender = '" + user + "' AND owner = '" + user + "'";
        } else if (folder.equals("trash")) {
            where = "folder = '3' AND (sender = '" + user + "' OR receiver = '" + user + "') AND owner = '" + user + "'";
        }
        Transaction tx = session.beginTransaction();
        List<PrivateMessage> list = session.createQuery("from PrivateMessage where " + where + " ORDER BY id DESC").setFirstResult(offset).setMaxResults(15).list();
        tx.commit();
        return list;
    }

    /**
     * Calculates the total of the private messages with the given folder and
     * user; To check if it is necessary to add pagination.
     *
     * @param folder
     * @param user
     * @return
     */
    public int getLastPage(String folder, long user) {
        String where = "(folder = '1') AND receiver = '" + user + "' AND owner = '" + user + "'";
        if (folder.equals("outbox")) {
            where = "folder = '2' AND sender = '" + user + "' AND owner = '" + user + "'";
        } else if (folder.equals("trash")) {
            where = "folder = '3' AND (sender = '" + user + "' OR receiver = '" + user + "') AND owner = '" + user + "'";
        }
        Transaction tx = session.beginTransaction();
        Query query = session.createSQLQuery("SELECT COUNT(*) FROM PrivateMessage where " + where);
        tx.commit();
        String i = "" + query.uniqueResult();
        return Integer.parseInt(i);
    }

    /**
     * Removes all the private messages who are located in the trash folder with
     * the given user.
     *
     * @param user
     */
    public void removeAllPrivateMessages(long user) {
        String where = "folder = '3' AND owner = '" + user + "'";
        Transaction tx = session.beginTransaction();
        session.createSQLQuery("DELETE FROM PrivateMessage WHERE " + where).executeUpdate();
        tx.commit();
    }

    public boolean save(PrivateMessage pm) {
        try {
            Transaction tx = session.beginTransaction();
            session.save(pm);
            tx.commit();
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    public boolean update(PrivateMessage pm) {
        try {
            Transaction tx = session.beginTransaction();
            session.update(pm);
            tx.commit();
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    public void delete(PrivateMessage pm) {
        Transaction tx = session.beginTransaction();
        session.delete(pm);
        tx.commit();
    }

    public PrivateMessage get(long id) {
        return (PrivateMessage) session.get(PrivateMessage.class, id);
    }
}
